﻿Imports System
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.Runtime.Serialization
Imports System.Security.Permissions

Namespace System.Workflow.Runtime
    <Serializable> _
    Friend Class TrackingListenerBroker
        Implements ISerializable
        ' Methods
        Friend Sub New()
            Me._services = New Dictionary([Of] Guid, ServiceProfileContainer)
        End Sub

        Friend Sub New(ByVal listener As TrackingListener)
            Me._services = New Dictionary([Of] Guid, ServiceProfileContainer)
            Me._listener = listener
        End Sub

        Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            Me._services = New Dictionary([Of] Guid, ServiceProfileContainer)
            Me._eventOrderId = info.GetInt32("eventOrderId")
            Me._services = DirectCast(info.GetValue("services", GetType(Dictionary([Of] Guid, ServiceProfileContainer))), Dictionary([Of] Guid, ServiceProfileContainer))
            If (Me._services Is Nothing) Then
                Me._services = New Dictionary([Of] Guid, ServiceProfileContainer)
            End If
        End Sub

        Friend Sub AddService(ByVal trackingServiceType As Type, ByVal profileVersionId As Version)
            Me._services.Add(HashHelper.HashServiceType(trackingServiceType), New ServiceProfileContainer(profileVersionId))
        End Sub

        Friend Function ContainsService(ByVal trackingServiceType As Type) As Boolean
            Return Me._services.ContainsKey(HashHelper.HashServiceType(trackingServiceType))
        End Function

        Friend Function GetNextEventOrderId() As Integer
            Return ++Me._eventOrderId
        End Function

        <SecurityPermission(SecurityAction.Demand, SerializationFormatter:=True)> _
        Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            info.AddValue("eventOrderId", Me._eventOrderId)
            info.AddValue("services", If((Me._services.Count = 0), Nothing, Me._services))
        End Sub

        Friend Function IsProfileInstance(ByVal trackingServiceType As Type) As Boolean
            Dim container As ServiceProfileContainer = Nothing
            If Not Me._services.TryGetValue(HashHelper.HashServiceType(trackingServiceType), container) Then
                Throw New ArgumentException(ExecutionStringManager.InvalidTrackingService)
            End If
            Return container.IsInstance
        End Function

        Friend Function IsProfilePrivate(ByVal trackingServiceType As Type) As Boolean
            Dim container As ServiceProfileContainer = Nothing
            If Not Me._services.TryGetValue(HashHelper.HashServiceType(trackingServiceType), container) Then
                Throw New ArgumentException(ExecutionStringManager.InvalidTrackingService)
            End If
            Return container.IsPrivate
        End Function

        Friend Sub MakeProfileInstance(ByVal trackingServiceType As Type)
            Dim container As ServiceProfileContainer = Nothing
            If Not Me._services.TryGetValue(HashHelper.HashServiceType(trackingServiceType), container) Then
                Throw New ArgumentException(ExecutionStringManager.InvalidTrackingService)
            End If
            container.IsPrivate = True
            container.IsInstance = True
        End Sub

        Friend Sub MakeProfilePrivate(ByVal trackingServiceType As Type)
            Dim container As ServiceProfileContainer = Nothing
            If Not Me._services.TryGetValue(HashHelper.HashServiceType(trackingServiceType), container) Then
                Throw New ArgumentException(ExecutionStringManager.InvalidTrackingService)
            End If
            container.IsPrivate = True
        End Sub

        Friend Sub RemoveService(ByVal trackingServiceType As Type)
            Me._services.Remove(HashHelper.HashServiceType(trackingServiceType))
        End Sub

        Friend Function TryGetProfileVersionId(ByVal trackingServiceType As Type, <Out> ByRef profileVersionId As Version) As Boolean
            profileVersionId = New Version(0, 0)
            Dim container As ServiceProfileContainer = Nothing
            If Me._services.TryGetValue(HashHelper.HashServiceType(trackingServiceType), container) Then
                profileVersionId = container.ProfileVersionId
                Return True
            End If
            Return False
        End Function


        ' Properties
        Friend WriteOnly Property TrackingListener As TrackingListener
            Set(ByVal value As TrackingListener)
                Me._listener = value
            End Set
        End Property


        ' Fields
        Private _eventOrderId As Integer
        <NonSerialized> _
        Private _listener As TrackingListener
        Private _services As Dictionary([Of] Guid, ServiceProfileContainer)

        ' Nested Types
        <Serializable> _
        Friend Class ServiceProfileContainer
            ' Methods
            Protected Sub New()
                Me._profileVersionId = New Version(0, 0)
            End Sub

            Friend Sub New(ByVal profileVersionId As Version)
                Me._profileVersionId = New Version(0, 0)
                Me._profileVersionId = profileVersionId
            End Sub


            ' Properties
            Friend Property IsInstance As Boolean
                Get
                    Return Me._isInstance
                End Get
                Set(ByVal value As Boolean)
                    Me._isInstance = value
                End Set
            End Property

            Friend Property IsPrivate As Boolean
                Get
                    Return Me._isPrivate
                End Get
                Set(ByVal value As Boolean)
                    Me._isPrivate = value
                End Set
            End Property

            Friend ReadOnly Property ProfileVersionId As Version
                Get
                    Return Me._profileVersionId
                End Get
            End Property


            ' Fields
            Private _isInstance As Boolean
            Private _isPrivate As Boolean
            Private _profileVersionId As Version
        End Class
    End Class
End Namespace

